package com.jsurf;

import static name.audet.samuel.javacv.jna.cxcore.*;
import static name.audet.samuel.javacv.jna.cv.*;

public class IntegralImage{
	
	private float[] intData;
	private int width;
	private int height;
	
	// Computes the integral image of image img.  Assumes source image to be a 
	// 32-bit floating point.  Returns IplImage of 32-bit float form.
	public void getIntegralImage(IplImage src) {
		// convert the image to single channel 32f
		IplImage img = SurfUtil.getGray(src);
		IplImage intImg = cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);

		// set up variables for data access
		width = img.width;
		height = img.height;
		float[] data = new float[width * height];
		img.getFloatBuffer().get(data);
		intData = new float[width * height];
		
		intImg.getFloatBuffer().get(intData);
		
		// first row only
		float rowSum = 0f;
		for (int x = 0; x < width; x++) {
			rowSum += data[x];
			intData[x] = rowSum;
			
			SurfUtil.total += rowSum;
		}
		
		// remaining cells are sum above and to the left
		for (int y = 1; y < height; y++) {
			rowSum = 0;
			for (int x = 0; x < width; x++) {
				rowSum += data[y * width + x];
				intData[y * width + x] = rowSum + intData[(y - 1) * width + x];
				
				SurfUtil.total += intData[y * width + x];
			}
		}
		
		// release the gray image
		cvReleaseImage(img.pointerByReference());
	}
	
	public int getWidth() {
		return width;
	}
	
	public int getHeight() {
		return height;
	}
	
	public float getValueAt(int column, int row) {
		return intData[row * width + column];
	}
}